package com.ibm.spatiotemp.server.framework.request;

import java.text.ParseException;

import org.apache.log4j.Logger;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ibm.spatiotemp.tools.DateParser;
import com.ibm.spatiotemp.tools.jsonParser;

public class Request {

	public static Logger logger = Logger.getLogger(Request.class);
	
		String qtype;
		String sessionid;
		String tenantid;
		String sourceid;

		String id;
		ArrayNode ids;
		Long start;
		Long end;
		
		/*data for insert to db*/
		JsonNode data;
		
		/*for informix implementation*/
		String startts;
		String endts;
		
		JsonNode bbox;
		
		/*position query parameters*/
		String time;
		JsonNode position;
		Double distance;
		
		private String json_string;
		private ObjectNode jnode;
		
		public Request(){
			jnode = jsonParser.newObjectNode();
		}
		
		public void setQtype(String qtype) {
			jsonParser.SetKeyandValue( jnode, "qtype", qtype);
			this.qtype = qtype;
		}

		public void setSessionid(String sessionid) {
			jsonParser.SetKeyandValue( jnode, "sessionid", sessionid);
			this.sessionid = sessionid;
		}

		public void setTenantid(String tenantid) {
			jsonParser.SetKeyandValue( jnode, "tenantid", tenantid);
			this.tenantid = tenantid;
		}

		public void setSourceid(String sourceid) {
			jsonParser.SetKeyandValue( jnode, "sourceid", sourceid);
			this.sourceid = sourceid;
		}

		public void setId(String id) {
			jsonParser.SetKeyandValue( jnode, "id", id);
			this.id = id;
		}

		public void setIds(ArrayNode ids) {
			jsonParser.SetKeyandValue( jnode, "ids", ids);
			this.ids = ids;
		}

		public void setData(JsonNode data) {
			this.data = data;
		}

		public void setStartts(String startts) throws ParseException {
			jsonParser.SetKeyandValue( jnode, "startts", startts);
			this.startts = startts;
			this.start = DateParser.getTimestamp(startts);
		}

		public void setEndts(String endts) throws ParseException {
			jsonParser.SetKeyandValue( jnode, "endts", endts);
			this.endts = endts;
			this.end = DateParser.getTimestamp(endts);
		}

		public void setBbox(JsonNode bbox) {
			this.bbox = bbox;
		}

		public void setTime(String time) {
			this.time = time;
		}

		public void setPosition(JsonNode position) {
			this.position = position;
		}

		public void setDistance(Double distance) {
			this.distance = distance;
		}
		
		/**
		 * only used in JUNIT Test!
		 * @param reqjsonstring
		 * @throws ParseException 
		 */
		public void setRequestContent(String reqjsonstring) throws ParseException{
			JsonNode jnode = (ObjectNode) jsonParser.fromString(reqjsonstring);
			/* required */
			qtype = (jnode.get("qtype")) !=null ? (jnode.get("qtype").asText()) : qtype;
			sessionid = jnode.get("sessionid")!=null ? jnode.get("sessionid").asText() : sessionid;
			tenantid = jnode.get("tenantid") != null ? jnode.get("tenantid").asText(): tenantid;
			sourceid = jnode.get("sourceid") != null ? jnode.get("sourceid").asText(): sourceid;

			/* optional */
			id = jnode.get("id")!=null ?  jnode.get("id").asText(): id;
			ids = (ArrayNode) ((ArrayNode) jnode.get("ids")!=null? jnode.get("ids"): ids);
			startts = jnode.get("start")!=null ? jnode.get("start").asText() : startts;
			if(startts != null)
				start = DateParser.getTimestamp(startts);

			endts = jnode.get("endts")!=null ? jnode.get("endts").asText() : startts;
			if(endts != null)
				end = DateParser.getTimestamp(endts);

			bbox = jnode.get("bbox") != null ?  jnode.get("bbox") : bbox;
			data = jnode.get("data") != null ? jnode.get("data") : data;
			time = jnode.get("time") != null ? jnode.get("time").asText() : time;
			position = (JsonNode) (jnode.get("position") != null ? jnode.get("time").asText() : position);
			JsonNode distnode = jnode.get("distance");
			if(distnode != null)
				distance = jnode.get("distance").asDouble();
//			distance = jnode.get("distance")!=null ? jnode.get("distance").asDouble(): distance;

		}

		/**
		 * 
		 * @param jnode
		 * @throws ParseException 
		 */
		public Request(ObjectNode jnode) throws ParseException{
			this.jnode = jnode;
			
			/* required */
			qtype = (jnode.get("qtype").asText());
			sessionid = jnode.get("sessionid").asText();
			tenantid = jnode.get("tenantid").asText();
			sourceid = jnode.get("sourceid").asText();

			if (qtype == null) {
				logger.error("qtype cannot be null");
				throw new RuntimeException("qtype cannot be null");
			}
			if (sessionid == null) {
				logger.error("sessionid cannot be null");
				throw new RuntimeException("sessionid cannot be null");
			}
			if (tenantid == null) {
				logger.error("tenantid cannot be null");
				throw new RuntimeException("tenantid cannot be null");
			}
			if (sourceid == null) {
				logger.error("sourceid cannot be null");
				throw new RuntimeException("sourceid cannot be null");
			}

			/* optional */
			id = jnode.get("id")!=null ?  jnode.get("id").asText(): id;
			ids = (ArrayNode) ((ArrayNode) jnode.get("ids")!=null? jnode.get("ids"): ids);
			startts = jnode.get("start")!=null ? jnode.get("start").asText() : startts;
			if(startts != null)
				start = DateParser.getTimestamp(startts);

			endts = jnode.get("endts")!=null ? jnode.get("endts").asText() : startts;
			if(endts != null)
				end = DateParser.getTimestamp(endts);

			bbox = jnode.get("bbox") != null ?  jnode.get("bbox") : bbox;
			data = jnode.get("data") != null ? jnode.get("data") : data;
			time = jnode.get("time") != null ? jnode.get("time").asText() : time;
			position = (JsonNode) (jnode.get("position") != null ? jnode.get("time").asText() : position);
			JsonNode distnode = jnode.get("distance");
			if(distnode != null)
				distance = jnode.get("distance").asDouble();

			json_string = jnode.toString();
		}
		
		/**
		 * 
		 * @param jsonstring
		 *            : request string
		 * @throws ParseException
		 */
		public Request(String jsonstring) throws ParseException {
			jnode = (ObjectNode) jsonParser.fromString(jsonstring);
			/* required */
			qtype = (jnode.get("qtype").asText());
			sessionid = jnode.get("sessionid").asText();
			tenantid = jnode.get("tenantid").asText();
			sourceid = jnode.get("sourceid").asText();

			if (qtype == null) {
				logger.error("qtype cannot be null");
				throw new RuntimeException("qtype cannot be null");
			}
			if (sessionid == null) {
				logger.error("sessionid cannot be null");
				throw new RuntimeException("sessionid cannot be null");
			}
			if (tenantid == null) {
				logger.error("tenantid cannot be null");
				throw new RuntimeException("tenantid cannot be null");
			}
			if (sourceid == null) {
				logger.error("sourceid cannot be null");
				throw new RuntimeException("sourceid cannot be null");
			}

			/* optional */
			/* optional */
			id = jnode.get("id")!=null ?  jnode.get("id").asText(): id;
			ids = (ArrayNode) ((ArrayNode) jnode.get("ids")!=null? jnode.get("ids"): ids);
			startts = jnode.get("start")!=null ? jnode.get("start").asText() : startts;
			if(startts != null)
				start = DateParser.getTimestamp(startts);

			endts = jnode.get("end")!=null ? jnode.get("end").asText() : endts;
			if(endts != null)
				end = DateParser.getTimestamp(endts);

			bbox = jnode.get("bbox") != null ?  jnode.get("bbox") : bbox;
			data = jnode.get("data") != null ? jnode.get("data") : data;
			time = jnode.get("time") != null ? jnode.get("time").asText() : time;
			position = (JsonNode) (jnode.get("position") != null ? jnode.get("time").asText() : position);
			JsonNode distnode = jnode.get("distance");
			if(distnode != null)
				distance = jnode.get("distance").asDouble();
			
			json_string = jsonstring;
		}
		

		public JsonNode getJnode() {
			return jnode;
		}
		
		public JsonNode get(String key){
			return jnode.get(key);
		}
		
		public Double getDistance() {
			return distance;
		}

		
		public JsonNode getPosition() {
			return position;
		}
		
		public String getTime() {
			return time;
		}

		public JsonNode getData() {
			return data;
		}
		
		public String toJsonString(){
			return json_string;
		}

		public String getSessionid() {
			return sessionid;
		}

		public String getStartts() {
			return startts;
		}

		public String getEndts() {
			return endts;
		}

		public String getTenantid() {
			return tenantid;
		}

		public String getSourceid() {
			return sourceid;
		}

		public String getId() {
			return id;
		}

		public ArrayNode getIds() {
			return ids;
		}

		public String getQtype() {
			return qtype;
		}

		public long getStart() {
			return start;
		}

		public long getEnd() {
			return end;
		}

		public JsonNode getBbox() {
			return bbox;
		}

	
}
